package com.shenmazong.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shenmazong.user.entity.TbSysUser;
import com.shenmazong.user.service.TbSysUserService;
import com.shenmazong.user.mapper.TbSysUserMapper;
import com.shenmazong.utils.ResultResponse;
import com.shenmazong.utils.TokenUtils;
import com.shenmazong.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 *
 */
@Service
public class TbSysUserServiceImpl extends ServiceImpl<TbSysUserMapper, TbSysUser>
    implements TbSysUserService{

    @Autowired
    TbSysUserMapper tbSysUserMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public ResultResponse add(TbSysUser tbSysUser) {
        //--1 判断是否为同名的用户
        // select user_id from tb_sys_user where user_name = 'david' limit 1
        QueryWrapper<TbSysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().select(TbSysUser::getUserId).eq(TbSysUser::getUserName, tbSysUser.getUserName());
        // 添加保护性操作
        wrapper.lambda().last("limit 1");

        TbSysUser sysUser = tbSysUserMapper.selectOne(wrapper);
        if(sysUser != null) {
            return ResultResponse.FAILED(600, "用户已经存在");
        }

        //--2 加密密码
        String hashed = BCrypt.hashpw(tbSysUser.getUserPass(), BCrypt.gensalt());
        tbSysUser.setUserPass(hashed);

        //--3 添加到库
        tbSysUserMapper.insert(tbSysUser);

        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse del(IdVo idVo) {
        //--1 判断是否存在
        TbSysUser tbSysUser = tbSysUserMapper.selectById(idVo.getId());
        if(tbSysUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 删除
        tbSysUserMapper.deleteById(idVo.getId());
        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse set(TbSysUser tbSysUser) {
        //--1 判断用户是否存在
        TbSysUser user = tbSysUserMapper.selectById(tbSysUser.getUserId());
        if(user == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 把密码清空
        tbSysUser.setUserPass(null);
        tbSysUser.setUserName(null);
        tbSysUser.setUpdateTime(null);

        //--3 修改倒库
        tbSysUserMapper.updateById(tbSysUser);

        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse get(IdVo idVo) {
        //--1 判断用户是否存在
        TbSysUser user = tbSysUserMapper.selectById(idVo.getId());
        if(user == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 脱密
        user.setUserPass(null);

        return ResultResponse.SUCCESS(user);
    }

    @Override
    public ResultResponse changePassWord(PasswordChangeVo passwordChangeVo) {
        //--1 判断是否存在
        TbSysUser sysUser = tbSysUserMapper.selectById(passwordChangeVo.getId());
        if(sysUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 判断原密码是否正确
        if (!BCrypt.checkpw(passwordChangeVo.getOldPassword(), sysUser.getUserPass())) {
            return ResultResponse.FAILED(403, "原密码不正确");
        }

        //--3 设置新密码
        String hashpw = BCrypt.hashpw(passwordChangeVo.getNewPassword(), BCrypt.gensalt());
        sysUser.setUserPass(hashpw);
        sysUser.setUpdateTime(null);
        tbSysUserMapper.updateById(sysUser);

        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse listByPage(PageInfoVo pageInfoVo) {
        //--1 构造分页信息
        Page<TbSysUser> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());

        //--2 分页查询
        QueryWrapper<TbSysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().orderByDesc(TbSysUser::getCreateTime);
        Page<TbSysUser> tbSysUserPage = tbSysUserMapper.selectPage(page, wrapper);

        //--3 脱密
        tbSysUserPage.getRecords().forEach(item -> {
            item.setUserPass(null);
        });

        //--4 返回分页数据
        return ResultResponse.SUCCESS(tbSysUserPage);
    }

    /**
     * @description 实现系统登录功能
     * @author 军哥
     * @date 2022/6/22 14:38
     * @version 1.0
     */
    @Override
    public ResultResponse login(LoginInfoVo loginInfoVo) {
        //--1 检查是否存在
        TbSysUser sysUser = tbSysUserMapper.selectOne(
                // select * from tb_sys_user where user_name='xxxx' limit 1
                new QueryWrapper<TbSysUser>().lambda().
                        eq(TbSysUser::getUserName, loginInfoVo.getUserName())
                        .last("limit 1")
        );
        if(sysUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 校验密码
        if(!BCrypt.checkpw(loginInfoVo.getPassWord(), sysUser.getUserPass())) {
            return ResultResponse.FAILED(403, "登录密码不正确");
        }

        //--3 生成token
        String token = TokenUtils.token()
                // 设置加密密码
                .setKey("123456")
                // 设置过期时间
                .setExpire(60 * 30)
                // 添加数据
                .setClaim("id", "" + sysUser.getUserId())
                .setClaim("userName", sysUser.getUserName())
                .setClaim("role", "admin")
                // 生成token
                .createToken();

        String key = "login_sys_" + sysUser.getUserId();
        redisTemplate.opsForValue().set(key, token, 2, TimeUnit.MINUTES);


        //--4 返回登录成功的信息
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setUserId(sysUser.getUserId());
        userInfoVo.setUserName(sysUser.getUserName());
        userInfoVo.setAccessToken(token);

        return ResultResponse.SUCCESS(userInfoVo);
    }
}




